package cn.wgspring.game.sevenwondersserver;

import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/join/{roomId}")
@Component
public class SocketServer {
    Logger log = LoggerFactory.getLogger(getClass());

    private static final ConcurrentHashMap<String, Room> ALL_SESSIONS = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "roomId") String roomId) {
        session.setMaxTextMessageBufferSize(1024 * 1024);
        boolean isNew = false;
        if (!ALL_SESSIONS.containsKey(roomId)) {
            ALL_SESSIONS.put(roomId, new Room());
            isNew = true;
        }
        Room room = ALL_SESSIONS.get(roomId);
        int num = room.join(session);
        if (isNew) {
            room.broadcastSystemMessage("房间创建成功，等待玩家加入");
            log.info("房间{}创建成功", roomId);
        }
        room.broadcastSystemMessage("玩家加入房间，当前人数: " + num);
        log.info("房间{}加入成功, 当前人数{}", roomId, num);
    }

    @OnMessage
    public void onMessage(String msg, Session session, @PathParam(value = "roomId") String roomId) {
        log.info("房间{}发来消息:{}", roomId, msg);
        if (msg.contains("请求移除其他用户")) {
            ALL_SESSIONS.get(roomId).removeAllExcept(session);
            return;
        }

        ALL_SESSIONS.get(roomId).onReceiveMessage(msg);
    }

    @OnClose
    public void onClose(Session session, @PathParam(value = "roomId") String roomId) {
        if (!ALL_SESSIONS.containsKey(roomId)) {
            return;
        }
        Room room = ALL_SESSIONS.get(roomId);
        int num = room.remove(session);
        room.broadcastSystemMessage("玩家离开房间，当前人数: " + num);
        log.info("玩家离开房间{}, 当前人数{}", roomId, num);

        if (room.roomIsEmpty()) {
            ALL_SESSIONS.remove(roomId);
            log.info("房间{}关闭", roomId);
        }
    }


    @OnError
    public void onError(Throwable throwable, @PathParam(value = "roomId") String roomId) {
        log.error("房间{}连接发生异常", roomId, throwable);
    }
}
